package com.laobiao.file_netty_lib.netty.server;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.laobiao.file_netty_lib.content.LoggerUtil;
import com.laobiao.file_netty_lib.exception.FileBaseException;
import com.laobiao.file_netty_lib.netty.server.handler.ServerDownloadBusiness;
import com.laobiao.file_netty_lib.netty.server.handler.ServerFileDeleteBusiness;
import com.laobiao.file_netty_lib.netty.server.handler.ServerFileListBusiness;
import com.laobiao.file_netty_lib.netty.server.handler.ServerMkdirBusiness;
import com.laobiao.file_netty_lib.netty.server.handler.ServerUploadBusiness;
//import com.laobiao.file_netty_lib.netty.server.handler.ServerUploadHandler;
import com.laobiao.file_netty_lib.packet.BasePacket;
import com.laobiao.file_netty_lib.packet.PacketType;
import com.laobiao.file_netty_lib.packet.command.BaseCommandPacket;
import com.laobiao.file_netty_lib.packet.command.CommandCirculationType;
import com.laobiao.file_netty_lib.packet.command.Mkdir.MkdirCommand;
import com.laobiao.file_netty_lib.packet.command.download.ClientFileDownloadCommand;
import com.laobiao.file_netty_lib.packet.command.fileDelete.FileDeleteCommand;
import com.laobiao.file_netty_lib.packet.command.filelist.FileListCommand;
import com.laobiao.file_netty_lib.packet.command.upload.FileUploadCommand;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
 * 原则上服务端不可挂断客户端 的连接
 * @author 38079
 *
 */
public class ServerHandler extends SimpleChannelInboundHandler<BasePacket>{
	private static final Logger logger=LoggerUtil.getLogger(ServerHandler.class);
	
	//业务命令缓存
	public static Map<String, ServerBusiness> businessCommandPacket=new ConcurrentHashMap<String, ServerBusiness>();
	@Override
	public void channelActive(ChannelHandlerContext ctx) throws Exception {
		logger.info("有客户端连接服务端！"+ctx.channel().remoteAddress().toString());
		super.channelActive(ctx);
	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, BasePacket msg) throws Exception {
		// TODO Auto-generated method stub
		logger.log(Level.CONFIG, "收到数据包！"+msg);
		String clientKey=ctx.channel().remoteAddress().toString()+"_"+msg.getBusinessGroup();
		if(msg.getPacketType()==PacketType.COMMAND) {//命令包
			BaseCommandPacket commandPacket=(BaseCommandPacket)msg;//收到的是命令包
			if(commandPacket.circulationType()==CommandCirculationType.BUSINESS) {//如果是业务命令
				if(commandPacket instanceof FileUploadCommand) {//文件上传命令包
					ServerUploadBusiness uploadBusiness=new ServerUploadBusiness((FileUploadCommand)commandPacket);
					businessCommandPacket.put(clientKey, uploadBusiness);
					return;
				}else if(commandPacket instanceof ClientFileDownloadCommand){//文件下载命令包
					ServerDownloadBusiness dowLoadBaBusiness=new ServerDownloadBusiness(ctx,(ClientFileDownloadCommand)commandPacket);
					businessCommandPacket.put(clientKey, dowLoadBaBusiness);
					return;
				}else if(commandPacket instanceof FileListCommand){//文件下载命令包
					ServerFileListBusiness fileListBusiness=new ServerFileListBusiness(ctx,(FileListCommand)commandPacket);
					businessCommandPacket.put(clientKey, fileListBusiness);
					return;
				}else if(commandPacket instanceof FileDeleteCommand){//文件下载命令包
					ServerFileDeleteBusiness fileDeleteBusiness=new ServerFileDeleteBusiness(ctx,(FileDeleteCommand)commandPacket);
					businessCommandPacket.put(clientKey, fileDeleteBusiness);
					return;
				}else if(commandPacket instanceof MkdirCommand){//文件下载命令包
					ServerMkdirBusiness mkdirBusiness=new ServerMkdirBusiness(ctx,(MkdirCommand)commandPacket);
					businessCommandPacket.put(clientKey, mkdirBusiness);
					return;
				}else {
					logger.log(Level.WARNING, "收到未知业务命令包！"+msg);
				}
			}else if(commandPacket.circulationType()==CommandCirculationType.PROCEDURE) {//如果是流程命令
				ServerBusiness businessPacket = businessCommandPacket.get(clientKey);//取业务命令
				if(businessPacket!=null) {
					businessPacket.hasPacket(ctx, commandPacket);
				}
				
			}else{
				throw new FileBaseException("不支持的命令流转类型！"+commandPacket.circulationType(), FileBaseException.ERR_PARAM_WRONG);
			}
		}else if(msg.getPacketType()==PacketType.DATA) {//数据包
			ServerBusiness businessPacket=businessCommandPacket.get(clientKey);//取业务命令
			if(businessPacket!=null) {
				businessPacket.hasPacket(ctx, msg);
			}
		}else {
			logger.log(Level.WARNING, "收到未知数据包，未定义的包类型！"+msg);
		}

	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
		logger.log(Level.WARNING, "发生错误！", cause);
		cleanBusinessCommands(ctx.channel().remoteAddress().toString());
	}
	
	/**
	 * 关闭连接时
	 * 
	 */
	@Override
	public void channelInactive(ChannelHandlerContext ctx) throws Exception {
		logger.info(ctx.channel().remoteAddress().toString()+"  关闭连接！");
		cleanBusinessCommands(ctx.channel().remoteAddress().toString());
//		ctx.channel().close();
//		ctx.channel().disconnect();
	}
	
	/**
	 * 清理业务缓存
	 * @param addressString
	 */
	public static void cleanBusinessCommands(String addressString) {
		Iterator<Entry<String, ServerBusiness>> iterator = businessCommandPacket.entrySet().iterator();
		while (iterator!=null && iterator.hasNext()) {
			Entry<String, ServerBusiness> next = iterator.next();
			String key = next.getKey();
			ServerBusiness business=next.getValue();
			if(key.startsWith(addressString)) {
				try {
					business.close();
				} catch (Exception e) {
					// TODO: handle exception
				}
				businessCommandPacket.remove(key);
			}
		}
	}
	
}
